package com.waimai1.waimai.controller;

import com.aliyun.tea.TeaException;
import com.auth0.jwt.interfaces.Claim;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.waimai1.waimai.common.BaseContext;
import com.waimai1.waimai.common.JWTUtil;
import com.waimai1.waimai.common.R;
import com.waimai1.waimai.dto.UserLoginDto;
import com.waimai1.waimai.dto.ZhuceDto;
import com.waimai1.waimai.entity.*;
import com.waimai1.waimai.exception.EnumException;
import com.waimai1.waimai.exception.NotErrorException;
import com.waimai1.waimai.service.*;
import com.wechat.pay.java.service.cashcoupons.model.SendCouponResponse;
import io.netty.util.internal.StringUtil;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.StringValue;
import org.apache.ibatis.javassist.tools.rmi.Sample;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import javax.print.DocFlavor;
import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.aliyun.tea.*;

@Slf4j
@RestController
@RequestMapping("/user")

public class UserController {

    @Autowired
    private JWTUtil jwtUtil;
    @Autowired
    private UserService userService;
    @Autowired
    public RedisTemplate<String, String> redisTemplate;
    @Autowired
    private ChoujiangService choujiangService;
    @Autowired
    private ChoujiangWhiteService choujiangWhiteService;
    @Autowired
    private ChoujiangResService choujiangResService;
    @Autowired
    private CouponPersonService couponPersonService;
    @Autowired
    private UserCenterService userCenterService;
    @Autowired
    private PageInfoService pageInfoService;
    @Autowired
    private WepayService wepayService;
    @Value("${SMSAccessKeyID}")
    private String AccessKeyID;
    @Value("${SMSAccessKeySecret}")
    private String AccessKeySecret;

    @PostMapping("/login")
    public R<UserLoginDto> login(@RequestBody String code) {
        User user = userService.getUserInfo(code);
        UserLoginDto userLoginDto=new UserLoginDto();
        BeanUtils.copyProperties(user,userLoginDto);
        //生成session
//        BaseContext.setopenId(user.getOpenid());
        String token = jwtUtil.createToken(user);
        user.setOpenid("");
        userLoginDto.setToken(token);
        return R.success(userLoginDto);
    }
    //根据id获取用户信息
    @GetMapping("/getUserById/{id}")
    public R<User> getUserById(@PathVariable Integer id){
        return R.success(userService.getById(id));
    }
    //获取用户信息
    @GetMapping("/takeUserInfo")
    public R<User> takeUserInfo() {
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getOpenid, BaseContext.getopenId())
        .eq(User::getAcid,BaseContext.getAcid());
        User user = userService.getOne(userLambdaQueryWrapper, false);
        //暂时不用couponChoice控制弹窗了
//        if (!StringUtil.isNullOrEmpty(user.getPhone())) {
//            //搜索未领代金券，前端弹窗领取）
//            LambdaQueryWrapper<CouponPerson> couponPersonLambdaQueryWrapper = new LambdaQueryWrapper<>();
//            couponPersonLambdaQueryWrapper.eq(CouponPerson::getPhone, user.getPhone())
//                    .eq(CouponPerson::getStatus, "未领取");
//            List<CouponPerson> coupons = couponPersonService.list(couponPersonLambdaQueryWrapper);
//            if (null != coupons && coupons.size() > 0) {
//                user.setCouponChoice(coupons.size());
//            }
//        }
//        把openid设置为空后返回
        user.setOpenid("");
        return R.success(user);
    }

    //判断是否有抽奖机会
    @GetMapping("/judgeChoujiangChoice")
    public R<Boolean> judgeChoujiangChoice() {
        //1.获取当前可用得抽奖活动
        Choujiang choujiang = choujiangService.getCurrentChoujiang();
        if (null == choujiang) {
            throw new NotErrorException(EnumException.NO_CHOUJIANG_CHOICE);
        }
//        获取用户信息
        User userRes = userService.getUserByOpenid();

        //2.判断积分要求
        if (choujiang.getCostPoint() > 0 && userRes.getUserPoint() < choujiang.getCostPoint()) {
            throw new NotErrorException(EnumException.NO_CHOUJIANG_CHOICE);
        }
//        3.判断抽奖次数
        if (choujiang.getPersonCount() != 0) {
//            获取已抽奖次数
            int count = choujiangResService.getCount(choujiang.getId());
            if (count >= choujiang.getPersonCount()) {
                throw new NotErrorException(EnumException.NO_CHOUJIANG_CHOICE);
            }
        }
//        4.判断白名单
        if (choujiang.getUseWhite() == 1) {
            if (null == userRes.getPhone()) {
                throw new NotErrorException(EnumException.NO_CHOUJIANG_CHOICE);
            }
            boolean inWhite = redisTemplate.opsForSet().isMember(BaseContext.getAcid()+":choujiangWhite", userRes.getPhone());
            if (!inWhite) {
                throw new NotErrorException(EnumException.NO_CHOUJIANG_CHOICE);
            }
        }
//        5.判断完毕
        return R.success(true);
    }

    //    发送短信验证码
    public static com.aliyun.dysmsapi20170525.Client createClient(String accessKeyId, String accessKeySecret) throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config()
                // 必填，您的 AccessKey ID
                .setAccessKeyId(accessKeyId)
                // 必填，您的 AccessKey Secret
                .setAccessKeySecret(accessKeySecret);
        // Endpoint 请参考 https://api.aliyun.com/product/Dysmsapi
        config.endpoint = "dysmsapi.aliyuncs.com";
        return new com.aliyun.dysmsapi20170525.Client(config);
    }

    @GetMapping("/sendSMS/{phone}")
    public R<String> sendSMS(@PathVariable String phone) throws Exception {


        String regex = "^((13[0-9])|(14[5,7,9])|(15([0-3]|[5-9]))|(166)|(17[0,1,3,5,6,7,8])|(18[0-9])|(19[8|9]))\\d{8}$";
        if (phone.length() != 11) {
            return R.err(500, "手机号应为11位数");
        } else {
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(phone);
            boolean isMatch = m.matches();
            if (!isMatch) {
                return R.err(500, "请填入正确的手机号");
            }
        }
        Random random = new Random();
        int randomNumber = random.nextInt(900000) + 100000; // 生成6位随机数（范围：100000-999999）
        String code = String.valueOf(randomNumber);
        // 请确保代码运行环境设置了环境变量 ALIBABA_CLOUD_ACCESS_KEY_ID 和 ALIBABA_CLOUD_ACCESS_KEY_SECRET。
        // 工程代码泄露可能会导致 AccessKey 泄露，并威胁账号下所有资源的安全性。以下代码示例使用环境变量获取 AccessKey 的方式进行调用，仅供参考，建议使用更安全的 STS 方式，更多鉴权访问方式请参见：https://help.aliyun.com/document_detail/378657.html
        com.aliyun.dysmsapi20170525.Client client = this.createClient(AccessKeyID, AccessKeySecret);
        com.aliyun.dysmsapi20170525.models.SendSmsRequest sendSmsRequest = new com.aliyun.dysmsapi20170525.models.SendSmsRequest()
                .setSignName("蓝臣科技")
                .setTemplateCode("SMS_276335241")
                .setPhoneNumbers(phone)
                .setTemplateParam("{\"code\":" + code + "}");
        com.aliyun.teautil.models.RuntimeOptions runtime = new com.aliyun.teautil.models.RuntimeOptions();
        try {
            // 复制代码运行请自行打印 API 的返回值
            com.aliyun.dysmsapi20170525.models.SendSmsResponse res = client.sendSmsWithOptions(sendSmsRequest, runtime);
            log.info("SendSmsResponse res:{}", res);
            if (!res.body.code.equals("OK")) {
                throw new NotErrorException(1007, "当天发送短信超量");
            }
        } catch (TeaException error) {
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } catch (Exception _error) {
            TeaException error = new TeaException(_error.getMessage(), _error);
            // 错误 message
            System.out.println(error.getMessage());
            // 诊断地址
            System.out.println(error.getData().get("Recommend"));
            com.aliyun.teautil.Common.assertAsString(error.message);
        } finally {
            String redisKey = BaseContext.getAcid()+":code" + phone;
            redisTemplate.opsForValue().set(redisKey, code);
            redisTemplate.expire(redisKey, 300, TimeUnit.SECONDS);
            return R.success("ok");
        }
    }

    @PostMapping("/zhuce")
    public R<Integer> zhuce(@RequestBody ZhuceDto resUser) {
//        如果验证码不正确，则返回
        String redisKey =BaseContext.getAcid()+ ":code" + resUser.getPhone();
        if (!redisTemplate.hasKey(redisKey) || !redisTemplate.opsForValue().get(redisKey).equals(resUser.getCode())) {
            throw new NotErrorException(1007, "效验码错误");
        }
        ;
        //如果phone修改过，判断是否有没领过的优惠券，
        LambdaQueryWrapper<User> userLambdaQueryWrapper = new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getAcid,BaseContext.getAcid()).eq(User::getOpenid, BaseContext.getopenId());
        if (!userService.update(resUser, userLambdaQueryWrapper)) {
            throw new NotErrorException(EnumException.NO_UPDATE);
        }
        return R.success(0);
//        if(!user.getPhone().equals(resUser.getPhone())){
        //搜索未领代金券，发放代金券，修改代金券状态为已领取(暂不采用这种方式，改为修改领取状态，前端弹窗领取）
//            LambdaQueryWrapper<CouponPerson> couponPersonLambdaQueryWrapper=new LambdaQueryWrapper<>();
//            couponPersonLambdaQueryWrapper.eq(CouponPerson::getPhone,resUser.getPhone())
//                    .eq(CouponPerson::getStatus,"未领取");
//            List<CouponPerson> coupons=couponPersonService.list(couponPersonLambdaQueryWrapper);
//            for(CouponPerson couponPerson : coupons){
//                SendCouponResponse res=wepayService.sendcoupon(couponPerson.getWeixinNo(),BaseContext.getopenId());
//                if(null==res.getCouponId()){
//                    throw new NotErrorException(EnumException.NO_SEND_COUPON);
//                }
//                couponPerson.setCouponId(res.getCouponId());
//                couponPerson.setStatus("已领取");
//                couponPerson.setGetTime(new Date());
//                if(!couponPersonService.updateById(couponPerson)){
//                    throw new NotErrorException(EnumException.NO_UPDATE);
//                };
//        }
    }
//领券
    @GetMapping("/takecoupon/{phone}")
    public R<String> takecoupon(@PathVariable String phone) {
        if (!StringUtil.isNullOrEmpty(phone)) {
            LambdaQueryWrapper<CouponPerson> couponPersonLambdaQueryWrapper = new LambdaQueryWrapper<>();
            couponPersonLambdaQueryWrapper.eq(CouponPerson::getAcid,BaseContext.getAcid())
                    .eq(CouponPerson::getPhone, phone)
                    .eq(CouponPerson::getStatus, "未领取");
            List<CouponPerson> coupons = couponPersonService.list(couponPersonLambdaQueryWrapper);
            for (CouponPerson couponPerson : coupons) {
                SendCouponResponse res = wepayService.sendcoupon(couponPerson.getWexinNo(), BaseContext.getopenId());
                if (null == res.getCouponId()) {
                    throw new NotErrorException(EnumException.NO_SEND_COUPON);
                }
                couponPerson.setCouponId(res.getCouponId());
                couponPerson.setStatus("已领取");
                couponPerson.setGetTime(new Date());
                if (!couponPersonService.updateById(couponPerson)) {
                    throw new NotErrorException(EnumException.NO_UPDATE);
                }
            }
        }
        return R.success("ok");
    }
    //获取团长信息
    @GetMapping("/getTuan")
    public R<List<User>> getTuan(){
        LambdaQueryWrapper<User> userLambdaQueryWrapper=new LambdaQueryWrapper<>();
        userLambdaQueryWrapper.eq(User::getAcid,BaseContext.getAcid())
                .eq(User::getSort,"团长");
        List<User> res=userService.list(userLambdaQueryWrapper);
        return  R.success(res);
    }
   @PostMapping("/applyTuanzhang")
    public R<String> applyTuanzhang(@RequestBody User user){
        user.setSort("团长待批准");
        if(!userService.updateById(user)){
            throw new NotErrorException(1007,"申请团长失败");
        }
        return R.success("ok");
   }
    //    获取客户中心图标按钮
//    @GetMapping("/getIconBtn")
//    public R<List<UserCenter>> takecoupon() {
//        return R.success(userCenterService.list());
//    }

    //保存内部用户白名单
    @PostMapping("/saveYuangongWhite")
    public R<String> saveYuangongWhite(@RequestBody List<String> phonesList) {
        redisTemplate.opsForSet().add(BaseContext.getAcid()+":yuangongWhite", phonesList.toArray(new String[0]));
        return R.success("ok");
    }

    //判断是否为内部用户白名单用户
    @GetMapping("/judgeYuangongWhite")
    public R<Boolean> judgeYuangongWhite() {
        Boolean flag = redisTemplate.opsForSet().isMember(BaseContext.getAcid()+":yuangongWhite", BaseContext.getPhone());
        return R.success(flag);
    }

    //查询内部用户白名单用户集合
    @GetMapping("/getYuangongWhite")
    public R<Set<String>> getYuangongWhite() {
        Set<String> yuangongWhite = redisTemplate.opsForSet().members(BaseContext.getAcid()+":yuangongWhite");
        return R.success(yuangongWhite);
    }

    //清空内部用户白名单用户集合
    @GetMapping("/clearYuangongWhite")
    public R<Boolean> clearYuangongWhite() {
        Boolean flag = redisTemplate.delete(BaseContext.getAcid()+":yuangongWhite");
        return R.success(flag);
    }
    //删除内部用户
    @PostMapping("/delYuangongWhite")
    public R<Long> delYuangongWhite(@RequestBody String phone){
        return R.success(redisTemplate.opsForSet().remove(BaseContext.getAcid()+":yuangongWhite",phone));
    }
}

